#include "thread_pool.hpp"
void queueInit(task_queue_t *que)
{
    if (que)
    {
        que->pFront = que->pRear = NULL;
        que->queueSize = 0;
        que->exit_flag = 0;
        int ret = pthread_mutex_init(&que->mutex, NULL);
        THREAD_ERROR_CHECK(ret, "pthread_mutex_init");
        ret = pthread_cond_init(&que->cond, NULL);
        THREAD_ERROR_CHECK(ret, "pthread_cond_init");
    }
}
void queueDestroy(task_queue_t *que)
{
    if (que)
    {
        int ret = pthread_mutex_destroy(&que->mutex);
        THREAD_ERROR_CHECK(ret, "pthread_mutex_destroy");
        ret = pthread_cond_destroy(&que->cond);
        THREAD_ERROR_CHECK(ret, "pthread_cond_destroy");
    }
}
int taskSize(task_queue_t *que)
{
    return que->queueSize;
}

int queueIsEmpty(task_queue_t *que)
{
    return que->queueSize == 0;
}
void taskEnqueue(task_queue_t *que, task_t *ptask)
{
    assert(que != NULL);
    pthread_mutex_lock(&que->mutex);
    if (queueIsEmpty(que))
    {
        que->pFront = que->pRear = ptask;
    }
    else
    {
        que->pRear->pNext = ptask;
        que->pRear = ptask;
    }
    que->queueSize++;
    pthread_cond_signal(&que->cond);
    pthread_mutex_unlock(&que->mutex);
}
task_t *taskDequeue(task_queue_t *que)
{
    assert(que != NULL);
    pthread_mutex_lock(&que->mutex);
    task_t *pret;
    while (!que->exit_flag && queueIsEmpty(que))
    {
        pthread_cond_wait(&que->cond, &que->mutex);
    }
    if (!que->exit_flag)
    {
        pret = que->pFront;
        if (taskSize(que) == 1)
        {
            que->pFront = que->pRear = nullptr;
        }
        else
        {

            que->pFront = que->pFront->pNext;
        }
        que->queueSize--;
    }
    else
    {
        pret = nullptr;
    }
    pthread_mutex_unlock(&que->mutex);
    return pret;
}